import json
import logging

from arq.connections import RedisSettings
from pydantic.v1 import BaseSettings, validator


class LoggingConfig(BaseSettings):
    level: str = "info"

    @validator("level")
    def level_must_exist(cls, value: str):
        if value.lower() not in ("error", "warning", "info", "debug"):
            raise ValueError("Level must be one of these: " "error, warning, info, debug")

        return logging.getLevelName(value.upper())


class DBConfig(BaseSettings):
    host: str
    port: int
    name: str
    user: str
    password: str
    echo: bool = False

    @property
    def full_url(self) -> str:
        return "mysql+aiomysql://{}:{}@{}:{}/{}".format(
            self.user,
            self.password,
            self.host,
            self.port,
            self.name,
        )


class Redis(BaseSettings):
    host: str
    port: int
    password: str
    database: int

    @property
    def url(self) -> str:
        return f"redis://default:{self.password}@{self.host}:{self.port}/{self.database}"

    @property
    def pool_settings(self) -> RedisSettings:
        return RedisSettings(
            host=self.host,
            port=self.port,
            database=self.database,
            password=self.password,
        )


class TgBot(BaseSettings):
    token: str
    admin_ids: list[int]
    developer_id: int
    use_redis: bool

    @validator("admin_ids", pre=True, always=True)
    def admin_ids_list(cls, v) -> list[int]:
        return json.loads(v)


class Api(BaseSettings):
    token: str
    shop_id: str


class Settings(BaseSettings):
    logging: LoggingConfig
    tg_bot: TgBot
    db: DBConfig
    redis: Redis
    api: Api

    class Config:
        env_file = ".env"
        env_file_encoding = "utf-8"
        env_nested_delimiter = "__"


def load_config(env_file=".env") -> Settings:
    settings = Settings(_env_file=env_file)
    return settings
